﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;


namespace GameStateManagement
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class DebrisSpawnManager : Microsoft.Xna.Framework.GameComponent
    {
        private int count;
        private Utils.Timer timers;
        private Game game;
        private Random random;
        private float length;

        private bool followCam;

        public List<Debris> activeDebris;

        public DebrisSpawnManager(Game game)
            : base(game)
        {
            this.game = game;
            random = new Random();
            timers = new Utils.Timer();
            length = 0.0f;
            followCam = true;

        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            // TODO: Add your initialization code here
            count = 0;
            activeDebris = new List<Debris>();
            timers.AddTimer("debrisTimer", 0.1f, new Utils.TimerDelegate(NewDebris), true);
            
            
            base.Initialize();
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
          



            // TODO: Add your update code here
            timers.Update(gameTime);
            base.Update(gameTime);
        }

        public void updateRadius(float rad){
            if (length == 0)
            {
                length = rad;
            }
        }
        public void switchCam()
        {
            followCam = !followCam;
            foreach (Debris deb in activeDebris)
            {
                if(deb.followCam != followCam)
                    deb.switchCam();
            }
        }
        void NewDebris()
        {
            if (count < 10)
            {
                

                bool tryAgain = false;
                Debris debris = new Debris(game);
                debris.followCam = followCam;

                float fzAngle, fyAngle;
                fzAngle = (float)(random.NextDouble() * Math.PI);
                fyAngle = (float)(random.NextDouble() * Math.PI);                
        

                float x = (this.length + 200.0f) * (float)(Math.Sin(fyAngle) * Math.Sin(fzAngle));
                float y = (this.length + 200.0f) * (float)Math.Cos(fyAngle);
                float z = (this.length + 200.0f) * (float)(Math.Sin(fyAngle) * Math.Cos(fzAngle));

                Vector3 pos = new Vector3(x, y, z);
                debris.Position = pos;
                debris.updateRotation();


                float leftVel = (float)(random.NextDouble() * 3.0f) + 2.0f;
                float upVel = (float)(random.NextDouble() * 3.0f) + 2.0f;

                if (random.NextDouble() > 0.5)
                {
                    leftVel = -leftVel;
                }
                if (random.NextDouble() > 0.5)
                {
                    upVel = -upVel;
                }

                debris.fLeftVel = leftVel;
                debris.fUpVel = upVel;

                foreach (Debris deb in activeDebris)
                {
                    if (debris.WorldBounds.Intersects(deb.WorldBounds))
                    {
                        tryAgain = true;
                        break;
                    }
                    BoundingSphere sphere = GameplayScreen.ship.WorldBounds;
                    sphere.Radius *= 8.0f;
                    if (debris.WorldBounds.Intersects(sphere))
                    {
                        tryAgain = true;
                        break;
                    }
                }

                if (!tryAgain)
                {
                    game.Components.Add(debris);
                    activeDebris.Add(debris);
                    count++;
                }
            }

        }
    }
}